package com.gagakuai.bpm.api.camunda;


import com.gagakuai.bpm.common.annotation.CurrentUserInfo;
import com.gagakuai.bpm.common.enums.BusinessCodeEnum;
import com.gagakuai.bpm.common.enums.FetchBackFailEnum;
import com.gagakuai.bpm.common.enums.WithDrawEnum;
import com.gagakuai.bpm.common.exception.BpmException;
import com.gagakuai.bpm.dao.mapper.camunda.ActHiActinstMapper;
import com.gagakuai.bpm.domian.dto.camunda.*;
import com.gagakuai.bpm.domian.dto.response.ResponseStatusDto;
import com.gagakuai.bpm.domian.entity.camuda.ActHiComment;
import com.gagakuai.bpm.domian.query.camunda.WorkflowQuery;
import com.gagakuai.bpm.domian.vo.camunda.ActivityNodeVO;
import com.gagakuai.bpm.service.camunda.InformService;
import com.gagakuai.bpm.service.camunda.WorkFlowPageQueryInterface;
import com.gagakuai.bpm.service.camunda.WorkflowTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.engine.history.HistoricProcessInstance;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/*
 * 定义业务规则：0:表示节点正在操作，4:表示正常流转完成，5：表示拒绝，6：表示退回重填，7表示退回上一步，8表示委托，9表示加签
 */
@RestController
@RequestMapping("/bpm/task")
@Api(tags = {"流程任务管理接口"})
public class WorkflowTaskController {

    @Resource
    private WorkflowTaskService workflowTaskService;

    @Resource
    private WorkFlowPageQueryInterface workFlowPageQueryInterface;

    @Resource
    private InformService informService;

    @Resource
    private ActHiActinstMapper actHiActinstMapper;


    @ApiOperation("启动流程实例")
    @PostMapping("/startProcess/{key}")
    public ResponseStatusDto<String> startProcess(@PathVariable String key, @RequestBody WorkflowVariableDto dto) throws Exception {
        if (StringUtils.isBlank(key)) {
            return ResponseStatusDto.failure("参数key不能为空");
        }

        if (ObjectUtils.isEmpty(dto.getStartUser()) || StringUtils.isBlank(dto.getStartUser())) {
            return ResponseStatusDto.failure("参数startUser[发起人]不能为空");
        }

        if (ObjectUtils.isEmpty(dto.getBusinessId()) || StringUtils.isBlank(dto.getBusinessId())) {
            return ResponseStatusDto.failure("businessId[业务ID]不能为空");
        }
        Thread.sleep(10);
        ResponseStatusDto<String> success = ResponseStatusDto.success(workflowTaskService.startProcess(key, dto));


        return success;
    }


    @ApiOperation("撤销已发起的流程")
    @PostMapping("/processDraw/{processId}")
    public ResponseStatusDto<Void> processDraw(@PathVariable("processId") String processId,
                                               @RequestBody @CurrentUserInfo UserInfo userInfo) throws Exception {
        if (StringUtils.isEmpty(processId)) {
            throw new BpmException(BusinessCodeEnum.PROCESSID_NOT_ALLOW_NULL);
        }
        int type = workflowTaskService.withDraw(processId, userInfo);
        return type == 0 ? ResponseStatusDto.success() : ResponseStatusDto.failure(WithDrawEnum.getMsgByCode(type));
    }


    @ApiOperation("退回重填")
    @PostMapping("/processDrawToStartStep/{processId}")
    public ResponseStatusDto<Void> processDrawToStartStep(@PathVariable("processId") String processId,
                                                          @RequestBody ActHiComment actHiComment) throws Exception {
        if (StringUtils.isEmpty(processId)) {
            throw new BpmException(BusinessCodeEnum.PROCESSID_NOT_ALLOW_NULL);
        }
        int type = workflowTaskService.processDrawToStart(processId, actHiComment);
        return type == 0 ? ResponseStatusDto.success() : ResponseStatusDto.failure(WithDrawEnum.getMsgByCode(type));
    }

    @ApiOperation("取回")
    @PostMapping("/processReturn/{processId}")
    public ResponseStatusDto<Void> processWithDraw(@PathVariable("processId") String processId,
                                                   @RequestBody ActHiComment actHiComment) throws Exception {
        if (StringUtils.isEmpty(processId)) {
            throw new BpmException(BusinessCodeEnum.PROCESSID_NOT_ALLOW_NULL);
        }
        int type = workflowTaskService.processReturn(processId, actHiComment);
        return type == 0 ? ResponseStatusDto.success() : ResponseStatusDto.failure(WithDrawEnum.getMsgByCode(type));
    }

    @ApiOperation("退回到上一步")
    @PostMapping("/processDrawToLastStep/{processId}")
    public ResponseStatusDto<Void> processDrawToLastStep(@PathVariable("processId") String processId,
                                                         @RequestBody @CurrentUserInfo ActHiComment actHiComment) throws Exception {
        if (StringUtils.isEmpty(processId)) {
            throw new BpmException(BusinessCodeEnum.PROCESSID_NOT_ALLOW_NULL);
        }
        int type = workflowTaskService.processDrawToLastStep(processId, actHiComment);
        return type == 0 ? ResponseStatusDto.success() : ResponseStatusDto.failure(WithDrawEnum.getMsgByCode(type));
    }


    @ApiOperation("完成任务")
    @PostMapping("/completeTask/{taskId}")
    public ResponseStatusDto<String> completeTask(@PathVariable String taskId, @RequestBody WorkflowVariableDto dto, @CurrentUserInfo UserInfo userInfo) {
        String result = workflowTaskService.completeTask(taskId, dto, userInfo);
        return ObjectUtils.isEmpty(result) ? ResponseStatusDto.success() : ResponseStatusDto.failure(result);
    }


    @ApiOperation("拒绝任务")
    @PostMapping("/rejectTask/{taskId}")
    public ResponseStatusDto<String> rejectTask(@PathVariable String taskId, @RequestBody WorkflowVariableDto dto, @CurrentUserInfo UserInfo userInfo) {
        String result = workflowTaskService.rejectTask(taskId, dto, userInfo);
        return ObjectUtils.isEmpty(result) ? ResponseStatusDto.success() : ResponseStatusDto.failure(result);
    }

    @ApiOperation("撤销任务")
    @PostMapping("/withDrawTask/{taskId}")
    public ResponseStatusDto<String> withDrawTask(@PathVariable String taskId, @RequestBody WorkflowVariableDto dto, @CurrentUserInfo UserInfo userInfo) {
        String result = workflowTaskService.withDrawTask(taskId, dto, userInfo);
        return ObjectUtils.isEmpty(result) ? ResponseStatusDto.success() : ResponseStatusDto.failure(result);
    }


    @ApiOperation("获取高亮节点Id")
    @GetMapping("/highLine/{processId}")
    public ResponseStatusDto<String> completeTask(@PathVariable("processId") String processId) {
        String result = workflowTaskService.getHighlight(processId);
        return ObjectUtils.isEmpty(result) ? ResponseStatusDto.failure() : ResponseStatusDto.success(result);
    }


    @ApiOperation("拒绝")
    @PostMapping("/reject/{taskId}")
    @ApiImplicitParams({@ApiImplicitParam(name = "processInstanceId", value = "流程实例ID", required = true),
            @ApiImplicitParam(name = "taskId", value = "任务ID", required = true),
            @ApiImplicitParam(name = "reason", value = "原因", required = true)})
    public ResponseStatusDto<String> reject(@RequestBody WorkTaskOperDto workTaskOperDto,
                                            @PathVariable("taskId") String taskId) {


        if (StringUtils.isBlank(workTaskOperDto.getProcInstId())) {
            return ResponseStatusDto.failure("参数：procInstId（流程列号），不能为空");
        }

        if (StringUtils.isBlank(workTaskOperDto.getTaskId())) {
            return ResponseStatusDto.failure("参数：taskId，不能为空");
        }

        if (StringUtils.isBlank(workTaskOperDto.getDescription())) {
            return ResponseStatusDto.failure("参数：description，不能为空");
        }


        /*
         *  驳回到
         */
        boolean b = workflowTaskService.reject(workTaskOperDto.getProcInstId(), taskId, workTaskOperDto.getDescription(), 0);

        return workflowTaskService.reject(workTaskOperDto.getProcInstId(), taskId, workTaskOperDto.getDelegation(), 0) ?
                ResponseStatusDto.success("驳回成功") : ResponseStatusDto.failure("驳回操作失败，请确认参数是否正确");
    }


    @ApiOperation("加签")
    @PostMapping("/addInstance/{processIns}")
    public ResponseStatusDto<String> addInstance(@PathVariable("processIns") String processIns, @RequestBody WorkflowVariableDto dto, @CurrentUserInfo UserInfo userInfo) throws Exception {

        String result = workflowTaskService.addInstance(processIns, dto);
        return ObjectUtils.isNotEmpty(result) ? ResponseStatusDto.success(result) : ResponseStatusDto.failure(result);
    }

    @ApiOperation("批量加签")
    @PostMapping("/list/addInstance/{processIns}")
    public ResponseStatusDto<String> addInstanceList(@PathVariable("processIns") String processIns, @RequestBody List<WorkflowVariableDto> dtoList, @CurrentUserInfo UserInfo userInfo) throws Exception {

        String result = null;
        for (WorkflowVariableDto dto : dtoList) {
           result = workflowTaskService.addInstance(processIns, dto);
        }
        return ObjectUtils.isNotEmpty(result) ? ResponseStatusDto.success(result) : ResponseStatusDto.failure(result);
    }


    @ApiOperation("获取流程表单")
    @GetMapping("/getStartFormData")
    public ResponseStatusDto<WorkflowFormData> getStartFormData(String id) {
        if (StringUtils.isBlank(id)) {
            return ResponseStatusDto.failure("参数ID不能为空");
        }

        return ResponseStatusDto.success(workflowTaskService.getStartFormData(id));
    }

    @ApiOperation("获取任务表单")
    @ApiImplicitParam(name = "taskId", value = "任务ID", dataType = "String", required = true, paramType = "query")
    @GetMapping("/getTaskFormData")
    public ResponseStatusDto<WorkflowFormData> getTaskFormData(String taskId) {
        if (StringUtils.isBlank(taskId)) {
            return ResponseStatusDto.failure("参数taskId[任务ID]不能为空");
        }
        return ResponseStatusDto.success(workflowTaskService.getTaskFormData(taskId));
    }


    @ApiOperation("获取流程实例")
    @PostMapping("/getMyProcessInstances")
    public ResponseStatusDto<List<HistoricProcessInstance>> getMyProcessInstances(@RequestBody WorkflowQuery workflowQueryDto) {
        return ResponseStatusDto.success(workflowTaskService.getMyProcessInstances(workflowQueryDto));
    }

    @ApiOperation("获取流程节点")
    @GetMapping("/getNodeIds")
    @ApiImplicitParam(name = "proInsId", value = "流程实例ID", required = true, dataType = "String", paramType = "query")
    public ResponseStatusDto<WorkflowNodesDto> getNodeIds(String proInsId) {
        return ResponseStatusDto.success(workflowTaskService.getNodeIds(proInsId));
    }


    @ApiOperation("认领任务")
    @GetMapping("/claimTask")
    @ApiImplicitParams({@ApiImplicitParam(name = "taskId", value = "任务ID", required = true),
            @ApiImplicitParam(name = "claimUser", value = "认领人", required = true)})
    public ResponseStatusDto<Void> claimTask(String taskId, String claimUser) {
        workflowTaskService.claimTask(taskId, claimUser);
        return ResponseStatusDto.success();
    }


    @ApiOperation("委托任务")
    @PostMapping("/delegateTask/{taskId}/{delgateUser}")
    @ApiImplicitParams({@ApiImplicitParam(name = "taskId", value = "任务ID", required = true),
            @ApiImplicitParam(name = "delegationUser", value = "任务接收人", required = true)})
    public ResponseStatusDto<Void> delegateTask(@PathVariable("taskId") String taskId, @PathVariable("delgateUser") String delegationUser,
                                                @RequestBody ActHiComment actHiComment) {

        //todo 意见需要加
        workflowTaskService.delegateTask(taskId, delegationUser,actHiComment);

        return ResponseStatusDto.success();
    }


    @ApiOperation("转办任务")
    @GetMapping("/tansforTask/{taskId}")
    @ApiImplicitParams({@ApiImplicitParam(name = "taskId", value = "任务ID", required = true),
            @ApiImplicitParam(name = "delegationUser", value = "任务接收人", required = true)})
    public ResponseStatusDto<Void> tansforTask(@PathVariable("taskId") String taskId, String delegationUser) {
        workflowTaskService.tansforTask(taskId, delegationUser);
        return ResponseStatusDto.success();
    }


    @ApiOperation("历史操作信息")
    @ApiImplicitParam(dataType = "String", name = "processInstanceId", value = "流程实例ID", required = true, paramType = "query")
    @GetMapping("/tableContent")
    public ResponseStatusDto<List<CommentDto>> tableContent(String processInstanceId) {
        if (StringUtils.isBlank(processInstanceId)) {
            return ResponseStatusDto.failure("参数：processInstanceId，不能为空");
        }

        return ResponseStatusDto.success(workflowTaskService.tableContent(processInstanceId));
    }

    @ApiOperation("获取高亮信息")
    @GetMapping("/getHighLine")
    @ApiImplicitParams({@ApiImplicitParam(name = "processInsId", value = "流程实例ID", required = true),
            @ApiImplicitParam(name = "authorId", value = "参与人")})
    public ResponseStatusDto<CamundaHighLineDTO> getHighLine(String processInsId, String authorId) {
        return ResponseStatusDto.success(workflowTaskService.getHighlightNode(processInsId, authorId));
    }


    @ApiOperation("个人申请")
    @PostMapping("/myStartProc")
    public ResponseStatusDto<List<MyProcDto>> myStartProc(@RequestBody MyProc myProc) {
        if (StringUtils.isBlank(myProc.getStartUserId())) {
            return ResponseStatusDto.failure("个人ID不能为空");
        }
        return ResponseStatusDto.success(workFlowPageQueryInterface.listMyProcessByPage(myProc));
    }

    @ApiOperation("参办任务")
    @PostMapping("/myTask")
    public ResponseStatusDto<List<MyProcDto>> myTask(@RequestBody MyTask myTask) {
        return ResponseStatusDto.success(workFlowPageQueryInterface.listMyTaskByPage(myTask));
    }

    @Deprecated
    @ApiOperation("手动知会--功能取消")
    @PostMapping("/inform")
    public ResponseStatusDto<Void> inform(@RequestBody Inform inform) {
        if (ObjectUtils.isEmpty(inform) || ObjectUtils.isEmpty(inform.getTaskId())
                || ObjectUtils.isEmpty(inform.getUserIdList())) {
            return ResponseStatusDto.failure("知会失败，参数不正确");
        }

        return workflowTaskService.inform(inform) ?
                ResponseStatusDto.success() : ResponseStatusDto.failure("知会失败");
    }

    @ApiOperation("手动知会--2")
    @GetMapping("/handleInfo")
    @ApiImplicitParams({@ApiImplicitParam(name = "taskId", value = "任务ID，不能为空", required = true),
            @ApiImplicitParam(name = "assignees", value = "需要知会的人ID，多个以逗号分隔", required = true)})
    public ResponseStatusDto<Void> handleInfo(String taskId, String assignees) {
        if (StringUtils.isEmpty(taskId)) {
            return ResponseStatusDto.failure("知会失败，taskId参数不正确");
        }

        if (StringUtils.isEmpty(assignees)) {
            return ResponseStatusDto.failure("知会失败，assignees参数不正确");
        }

        String resultInfo = workflowTaskService.handleInfo(taskId, assignees);
        return StringUtils.isBlank(resultInfo) ? ResponseStatusDto.success() : ResponseStatusDto.failure(resultInfo);
    }

    @Deprecated
    @ApiOperation("知会：已阅  功能取消")
    @GetMapping("/readed")
    @ApiImplicitParams({@ApiImplicitParam(name = "taskId", value = "任务ID，不能为空", required = true),
            @ApiImplicitParam(name = "reason", value = "填写原因", required = true)})
    public ResponseStatusDto<Void> readed(String taskId, String reason) {
        if (StringUtils.isBlank(taskId)) {
            return ResponseStatusDto.failure("已阅失败，参数[taskId] 不能不空");
        }

        if (StringUtils.isBlank(reason)) {
            return ResponseStatusDto.failure("已阅失败，参数[reason] 不能不空");
        }

        String msg = informService.readed(taskId, reason);
        return StringUtils.isBlank(msg) ? ResponseStatusDto.success() : ResponseStatusDto.failure(msg);
    }

    @ApiOperation("知会：已阅2")
    @GetMapping("/readed2")
    @ApiImplicitParams({@ApiImplicitParam(name = "taskId", value = "任务ID，不能为空", required = true),
            @ApiImplicitParam(name = "reason", value = "填写原因", required = true)})
    public ResponseStatusDto<Void> readed2(String taskId, String reason) {
        if (StringUtils.isBlank(taskId)) {
            return ResponseStatusDto.failure("已阅失败，参数[taskId] 不能不空");
        }

        if (StringUtils.isBlank(reason)) {
            return ResponseStatusDto.failure("已阅失败，参数[reason] 不能不空");
        }

        String msg = workflowTaskService.readed(taskId, reason);
        return StringUtils.isBlank(msg) ? ResponseStatusDto.success() : ResponseStatusDto.failure(msg);
    }

    @ApiOperation("取回: 参数procId 为流程实例ID")
    @GetMapping("/fetchBack")
    @ApiImplicitParam(name = "procId", value = "流程实例ID", required = true)
    public ResponseStatusDto<Void> fetchBack(String procId, @CurrentUserInfo UserInfo userInfo) {
        if (StringUtils.isEmpty(procId)) {
            return ResponseStatusDto.failure("取回失败，流程实例ID不正确");
        }
        int type = workflowTaskService.fetchBack(procId, userInfo);
        return type == 0 ? ResponseStatusDto.success() : ResponseStatusDto.failure(FetchBackFailEnum.getMsgByCode(type));
    }

    @ApiOperation("撤回: 参数procId 为流程实例ID")
    @GetMapping("/withDraw")
    @ApiImplicitParam(name = "procId", value = "流程实例ID", required = true)
    public ResponseStatusDto<Void> withDraw(String procId, @CurrentUserInfo UserInfo userInfo) throws Exception {
        if (StringUtils.isEmpty(procId)) {
            return ResponseStatusDto.failure("撤回失败，参数不正确");
        }

        int type = workflowTaskService.withDraw(procId, userInfo);
        return type == 0 ? ResponseStatusDto.success() : ResponseStatusDto.failure(WithDrawEnum.getMsgByCode(type));
    }

    @ApiOperation("流程执行详细")
    @GetMapping("/comment")
    @ApiImplicitParam(name = "procId", value = "流程实例ID", required = true)
    public ResponseStatusDto<List<TaskCommentDto>> comment(String procId) {
        if (StringUtils.isBlank(procId)) {
            return ResponseStatusDto.failure("流程实例ID不能为空");
        }

        return ResponseStatusDto.success(workFlowPageQueryInterface.comment(procId));
    }

    @ApiOperation("获取正在运行的任务")
    @GetMapping("/getMineRunningTask")
    public ResponseStatusDto<List<String>> getMineRunningTask(@CurrentUserInfo UserInfo user) {
        if (StringUtils.isBlank(user.getUserId())) {
            return ResponseStatusDto.failure("流程实例ID不能为空");
        }

        return ResponseStatusDto.success(workFlowPageQueryInterface.getMineRunningTask(user.getUserId()));
    }


    @ApiOperation("获取流程用户任务节点信息")
    @GetMapping("/getActivityNodeList")
    @ApiImplicitParam(name = "procId", value = "流程实例Id", required = true)
    public ResponseStatusDto<List<ActivityNodeVO>> getActivityNodeList(String procId) {
        if (StringUtils.isBlank(procId)) {
            return ResponseStatusDto.failure("流程实例ID不能为空");
        }

        return ResponseStatusDto.success(workflowTaskService.getActivityNodeList(procId));
    }


    public static void main(String[] args) {


        String test = "select " +
                "       c.TIME_ time, c.USER_ID_ userId, c.TASK_ID_ taskId, c.FULL_MSG_ fullMsg, " +
                "       u.FIRST_ userName, " +
                "       t.NAME_ taskName " +
                " from ACT_HI_COMMENT c " +
                " left join ACT_ID_USER u on c.USER_ID_ = u.ID_ " +
                " left join ACT_HI_TASKINST t on t.ID_ = c.TASK_ID_ " +
                " where c.PROC_INST_ID_ = #{processInstanceId} ";

        System.out.println(test);


    }
}
